﻿using AntMovement.Core.Entity;
using AntMovement.Core.Hardware;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace AntMovernent.SolidTechESerialCard.Logic
{
    public class AxitHardware : IAxis
    {
        private Axis _axit;
        public AxitHardware(Axis axis)
        {
            _axit = axis;
        }

        public string ClearCEnc()
        {
            int error = SLDMV.SLDM_Set_Enc(_axit.CardNo, _axit.AxisID, 0);
            if (error != 0)
            {
                throw new Exception($"CardNo[{_axit.CardNo}] Index[{_axit.AxisID}] Solid Tech E ==>> SLDM_Set_Enc[{error}]");
            }
            return "ok";
        }

        public string ClearCPos()
        {
            int error = SLDMV.SLDM_Set_Cpos(_axit.CardNo, _axit.AxisID, 0);
            if (error != 0)
            {
                throw new Exception($"CardNo[{_axit.CardNo}] Index[{_axit.AxisID}] Solid Tech E ==>> SLDM_Set_Cpos[{error}]");
            }
            return "ok";
        }

        public string ContinuousMotion(bool bl)
        {
            int error = 0;
            if (bl)
            {
                error = SLDMV.SLDM_JogP(_axit.CardNo, _axit.AxisID, (float)_axit.Parameter.Jog_Min_Vel, (float)_axit.Parameter.Jog_Max_Vel, (float)_axit.Parameter.Jog_Tacc);
                if (error != 0)
                {
                    throw new Exception($"CardNo[{_axit.CardNo}] Index[{_axit.AxisID}] Solid Tech E ==>> SLDM_JogP[{error}]");
                }
            }
            else
            {
                error = SLDMV.SLDM_JogM(_axit.CardNo, _axit.AxisID, (float)_axit.Parameter.Jog_Min_Vel, (float)_axit.Parameter.Jog_Max_Vel, (float)_axit.Parameter.Jog_Tacc);
                if (error != 0)
                {
                    throw new Exception($"CardNo[{_axit.CardNo}] Index[{_axit.AxisID}] Solid Tech E ==>> SLDM_JogM[{error}]");
                }
            }
            return "ok";
        }

        public AxisParameter GetAxisParameter() => _axit.Parameter;

        public AxisStatus GetAxisStatus() => _axit.Status;

        public string HomeMove()
        {
            //0-正向，1-反向
            int error = SLDMV.SLDM_Set_Home_Para(_axit.CardNo, _axit.AxisID, (uint)(_axit.Parameter.Home_dir ? 0 : 1), (float)_axit.Parameter.Low_Vel, (float)_axit.Parameter.High_Vel, (float)_axit.Parameter.HomeTargetSpeed, _axit.Parameter.Mode, _axit.Parameter.IptMode);
            if (error != 0)
            {
                throw new Exception($"CardNo[{_axit.CardNo}] Index[{_axit.AxisID}] Solid Tech E ==>> SLDM_Set_Home_Para[{error}]");
            }
            error = SLDMV.SLDM_Set_Home_Oft(_axit.CardNo, _axit.AxisID, 0);
            if (error != 0)
            {
                throw new Exception($"CardNo[{_axit.CardNo}] Index[{_axit.AxisID}] Solid Tech E ==>> SLDM_Set_Home_Oft[{error}]");
            }
            error = SLDMV.SLDM_Set_Soft_Limit(_axit.CardNo, _axit.AxisID, (uint)(_axit.Parameter.Enable_Plimit ? 1 : 0), (int)_axit.Parameter.SPostiveLimitedP, (int)_axit.Parameter.SNeativeLimitedP);
            if (error != 0)
            {
                throw new Exception($"CardNo[{_axit.CardNo}] Index[{_axit.AxisID}] Solid Tech E ==>> SLDM_Set_Soft_Limit[{error}]");
            }
            error = SLDMV.SLDM_Home_Move(_axit.CardNo, _axit.AxisID);
            if (error != 0)
            {
                throw new Exception($"CardNo[{_axit.CardNo}] Index[{_axit.AxisID}] Solid Tech E ==>> SLDM_Set_Soft_Limit[{error}]");
            }
            return "ok";
        }

        public string Move(long dist, int dist_mode, int vel_mode)
        {
            int error = 0;
            switch (dist_mode)
            {
                case 0:
                    error = SLDMV.SLDM_PTP1R(_axit.CardNo, _axit.AxisID, (int)dist, (float)_axit.Parameter.Min_Vel, (float)_axit.Parameter.Max_Vel, (float)_axit.Parameter.Stop_Vel, (float)_axit.Parameter.STacc, (float)_axit.Parameter.STdec, _axit.Parameter.s_mode);
                    if (error != 0)
                    {
                        throw new Exception($"CardNo[{_axit.CardNo}] Index[{_axit.AxisID}] Solid Tech E ==>> SLDM_PTP1R[{error}]");
                    }
                    break;
                case 1:
                    error = SLDMV.SLDM_PTP1(_axit.CardNo, _axit.AxisID, (int)dist, (float)_axit.Parameter.Min_Vel, (float)_axit.Parameter.Max_Vel, (float)_axit.Parameter.Stop_Vel, (float)_axit.Parameter.STacc, (float)_axit.Parameter.STdec, _axit.Parameter.s_mode);
                    if (error != 0)
                    {
                         throw new Exception($"CardNo[{_axit.CardNo}] Index[{_axit.AxisID}] Solid Tech E ==>> SLDM_PTP1[{error}]");
                    }
                    break;
            }
            return "ok";
        }

        public string SetProfile()
        {
            return "ok";
        }

        public string SetServo(bool enable)
        {
            int error = SLDMV.SLDM_Set_ServoOn(_axit.CardNo, _axit.AxisID, (uint)(enable ? 1 : 0));
            if (error != 0)
            {
                throw new Exception($"CardNo[{_axit.CardNo}] Index[{_axit.AxisID}] Solid Tech E ==>> SLDM_Stop[{error}]");
            }
            return "ok";
        }

        public string Stop(int emgStop)
        {
            int error = 0;
            switch (emgStop) 
            {
                case 0:
                    error = SLDMV.SLDM_Stop(_axit.CardNo, _axit.AxisID, (float)_axit.Parameter.Stop_Vel);
                    if (error != 0)
                    {
                        throw new Exception($"CardNo[{_axit.CardNo}] Index[{_axit.AxisID}] Solid Tech E ==>> SLDM_Stop[{error}]");
                    }
                    break; 
                case 1:
                    error = SLDMV.SLDM_Estop(_axit.CardNo, _axit.AxisID);
                    if (error != 0)
                    {
                        throw new Exception($"CardNo[{_axit.CardNo}] Index[{_axit.AxisID}] Solid Tech E ==>> SLDM_Estop[{error}]");
                    }
                    break;
            }
            return "ok";
        }
    }
}
